Loading plugins in runtime
One of the WOLF objectives is to free the end-user of implementing anything, include and/or link plugins and packages in its applications.
This is accomplished with a combination of factory-based creation and automatic runtime loading of plugins.
The procedure has two main steps:
Search required plugins recursively in the YAML configuration file
Load required plugins
As result of this loading, the creators will be registered to the corresponding factories and the installed schema folders will be registered to the folder registry.
Important
The required plugins must be already compiled and installed.
WOLF loader
The responsible of loading the plugins (and ROS2 packages) in runtime is the class wolf::Loader:
#include <dlfcn.h>
#include <string>
#include <map>
#include <memory>
#include "yaml-cpp/yaml.h"
namespace wolf
{
class Loader
{
protected:
int flags_;
std::map<std::string, void*> name_resources_;
public:
Loader(int flags = RTLD_LAZY);
~Loader();
void load(std::string _libname_with_so);
void loadPlugin(std::string _plugin);
void close(std::string _libname_with_so);
void closePlugin(std::string _plugin);
void* isLoaded(std::string _libname_with_so) const;
void* isLoadedPlugin(std::string _plugin) const;
void searchAndLoadPlugins(const YAML::Node& _node);
static std::set<std::string> searchPlugins(const YAML::Node& _node, std::list<YAML::Node>& _visited_nodes);
static std::set<std::string> searchFieldsRecursive(const YAML::Node& _node,
std::list<YAML::Node>& _visited_nodes,
const std::string& field);
size_t size() const;
};
typedef std::shared_ptr<Loader> LoaderPtr;
} // namespace wolf
In Problem, there is a LoaderPtr that loads and keeps the loaded .so files.
Schema folder registry
Installed schemas
Along with the headers and the .so file, when installing a WOLF plugin the folder containing the schema files is also installed.
#install schemas
install(DIRECTORY schema
DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME})
Folder registry
Analogously to the factories, WOLF has the class FolderRegistry that keeps a
map of string, string being the key the plugin name and the value, the path of the installed schema folder.
The registration of these folders is performed at plugin loading time.
Then, after all necessary plugins are loaded in runtime, we can take the
vector of paths containing installed schemas direcly from the FolderRegistry.
The following is the part of Problem::autoSetup method that loads the plugins and retrieves the installed schema folders.
_loader->searchAndLoadPlugins(server.getNode());
// Add the installed schema folders after optional input folders
server.addFolderSchema(FolderRegistry::getRegisteredFolders());
Note
When a plugin is loaded , youshould see the following message in the console that confirms that the schema folder of this plugin has been correctly registered:
FolderRegistry <-- registered 'core' folder: /usr/local/include/wolf/core/schema
Note
The loading of ROS2 packages work analogously to plugins. It also registers subscribers and publishers creators and schema folders.